package server.core;

import server.*;
import server.util.FileUtil;
import server.valves.ValveBase;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;

final class StandardHostValve extends ValveBase {
    private static final String info = "server.core.StandardHostValve/1.0";
    private static final String faviconPath = System.getProperty("user.dir") + File.separator + "webapps" + File.separator + "favicon.ico";
    public String getInfo() {
        return info;
    }

    @Override
    public void invoke(Request request, Response response, ValveContext valveContext) throws IOException, ServletException {
        HttpServletRequest hreq = (HttpServletRequest)(request.getRequest());
        HttpServletResponse hres = ((HttpServletResponse)response.getResponse());
        String uri = ((HttpRequest)request).getDecodedRequestURI();
        if ("/favicon.ico".equals(uri)) {
            if (sendFavicon(hres.getOutputStream()))
                return;
        }

        StandardHost host = (StandardHost) getContainer();
        Context context = (Context) host.map(request, true);
        if (context == null) {
            hres.sendError(HttpServletResponse.SC_NOT_FOUND, hreq.getRequestURI());
            return;
        }
        String sessionId = hreq.getRequestedSessionId();
        //刷新session的访问时间
        if (sessionId != null) {
            Manager manager = context.getManager();
            if (manager != null) {
                Session session = manager.findSession(sessionId);
                if (session != null && session.isValid())
                    session.access();
            }
        }
        context.invoke(request, response);
    }

    private boolean sendFavicon(OutputStream stream) {
        File file = new File(faviconPath);
        if (!file.exists() || !file.isFile())
            return false;
        try {
            FileUtil.sendData(file, stream);
        } catch (Throwable t) {
            return false;
        }
        return true;
    }
}
